package com.hccl.mongoEntities;

import java.util.ArrayList;
import java.util.List;

import com.hccl.config.MongoDB;
import com.hccl.mongoEntities.CommandEntity;
import com.hccl.mongoEntities.NoMatchOrInputEntity;
import entities.Reply;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.annotations.*;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.UpdateOperations;

@Entity(value = "menus", noClassnameStored = true)
public class NavigationEntity {
    @Id
    protected String id;

    public List<Reply> getReply() {
        return reply;
    }

    public void setReply(List<Reply> reply) {
        this.reply = reply;
    }

    protected List<Reply> reply;
    @Reference(idOnly=true,lazy=true)
    private NavigationEntity parent;
    @Reference(idOnly=true,lazy=true)
    protected List<NavigationEntity> subStateNode=new ArrayList<NavigationEntity>();
    protected int level;
    @Reference(idOnly=true,lazy=true)
    protected List<GrammarRuleEntity> rules = new ArrayList<GrammarRuleEntity>();
    protected List<String> corpus = new ArrayList<String>();;
    protected Reply reListenReply;
    protected List<String> conflictList = new ArrayList<>();
    protected List<CommandEntity> commands;
    protected Reply helpReply;
    protected NoMatchOrInputEntity noMatch;
    protected NoMatchOrInputEntity noInput;
    protected String init_process;

//    public NavigationEntity(NavigationEntity parent){
//        this.parent = parent;
//    }

    public String getInit_process() {
        return init_process;
    }

    public void setInit_process(String init_process) {
        this.init_process = init_process;
    }

    public List<NavigationEntity> getSubStateNode() {
        return subStateNode;
    }

    public List<CommandEntity> getCommands() {
        return commands;
    }

    public void setCommands(List<CommandEntity> commands) {
        this.commands = commands;
    }

    public void setSubStateNode(List<NavigationEntity> subStateNode) {
        this.subStateNode = subStateNode;
    }

    public Reply getReListenReply() {
        return reListenReply;
    }

    public void setReListenReply(Reply reListenReply) {
        this.reListenReply = reListenReply;
    }

    public List<String> getConflictList() {
        return conflictList;
    }

    public void setConflictList(List<String> conflictList) {
        this.conflictList = conflictList;
    }

    public List<String> getCorpus() {
        return corpus;
    }

    public void setCorpus(List<String> corpus) {
        this.corpus = corpus;
    }

    public Reply getHelpReply() {
        return helpReply;
    }

    public void setHelpReply(Reply helpReply) {
        this.helpReply = helpReply;
    }

    public NoMatchOrInputEntity getNoMatch() {
        return noMatch;
    }

    public void setNoMatch(NoMatchOrInputEntity noMatch) {
        this.noMatch = noMatch;
    }

    public NoMatchOrInputEntity getNoInput() {
        return noInput;
    }

    public void setNoInput(NoMatchOrInputEntity noInput) {
        this.noInput = noInput;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public NavigationEntity getParent() {
        return parent;
    }

    public void setParent(NavigationEntity parent) {
        this.parent = parent;
    }

    public List<GrammarRuleEntity> getRules() {
        return rules;
    }

    public void setRules(List<GrammarRuleEntity> rules) {
        this.rules = rules;
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    @PrePersist
    public void prePersist() {

        if(null==parent){
            level = 1;
        }
        else{
            level = parent.getLevel()+1;
        }
    }

    @PostPersist
    public void postPersist() {

        if(null!=parent){
            for (NavigationEntity c : parent.getSubStateNode()){
                if(c.getId().equals(id)){
                    return;
                }
            }
            Datastore mongoDatastore = MongoDB.instance().getDatabase();
            UpdateOperations<NavigationEntity> ops = mongoDatastore
                    .createUpdateOperations(NavigationEntity.class).add("children",
                            getId(),false);
            Query<NavigationEntity> updateQuery = mongoDatastore
                    .createQuery(NavigationEntity.class).field("_id").equal(parent.getId());
            mongoDatastore.update(updateQuery, ops);
            parent.getSubStateNode().add(this);
        }
    }


}